﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using GCELibrary.Current;
using ZF.BLL.Linq;
namespace ZF.BLL.UserControls
{
    public class GridView : System.Web.UI.WebControls.GridView,  IPostBackEventHandler,IFilterExpressionContainer
    {
        #region 条件查询
        /// <summary>
        /// 表达式集合
        /// </summary>
        IList<FilterExpression> Params
        {
            get 
            { 
                if(ViewState[this.ClientID+"_FilterExpression"]==null)
                {
                    ViewState[this.ClientID + "_FilterExpression"] = new List<FilterExpression>();
                }
                return (IList<FilterExpression>)ViewState[this.ClientID + "_FilterExpression"];
            }
        }
        /// <summary>
        /// 添加一个表达式
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="values"></param>
        public void AddFilterExpression(string predicate, params object[] values)
        {
            //查找相似的
            var similar = Params.Where(p => p.Predicate == predicate);
            foreach (var param in similar)
            {
                bool eq = param.Values.Length == values.Length;
                if (eq)
                {
                    for (int i = 0; i < values.Length; i++)
                    {
                        if (!(eq && param.Values[i].Equals(values[i])))
                            eq = false;
                    }
                }
                if (eq)//如果已经发现相同的，则不添加
                    return;
            }
            Params.Add(new FilterExpression() { Predicate = predicate, Values = values });
            this.PageIndex = 0;
        }
        /// <summary>
        /// 移除表达式
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="values"></param>
        public void RemoveFilterExpression(string predicate, params object[] values)
        {
            //查找相似的
            var similar = Params.Where(p => p.Predicate == predicate);
            foreach (var param in similar)
            {
                bool eq = param.Values.Length == values.Length;
                if (eq)
                {
                    for (int i = 0; i < values.Length; i++)
                    {
                        if (!(eq && param.Values[i].Equals(values[i])))
                            eq = false;
                    }
                }
                if (eq)//如果已经发现相同的，则移除
                    Params.Remove(param);
            }
        }
        /// <summary>
        /// 移除所有符合条件的表达式
        /// </summary>
        /// <param name="predicate"></param>
        public void RemoveAllFilterExpression(string predicate)
        {
            var similar = Params.Where(p => p.Predicate == predicate);
            foreach (var param in similar)
            {
                Params.Remove(param);
            }
        }
        /// <summary>
        /// 移除所有的表达
        /// </summary>
        public void RemoveAllFilterExpression()
        {
            Params.Clear();
        }
        /// <summary>
        /// 返回表达式集合
        /// </summary>
        /// <returns></returns>
        public  IList<FilterExpression> GetExpressions()
        {
            return Params.ToList();
        }
        /// <summary>
        /// 是否有过滤查询
        /// </summary>
        public bool IsFilter { get { return GetExpressions().Count > 0; } }
        #endregion

        #region 分页
        /// <summary>
        /// 获取在 System.Web.UI.WebControls.GridView 控件中显示数据源记录所需的页数。
        /// </summary>
        public override int PageCount
        {
            get
            {
                if (this.RowCount % this.PageSize == 0)
                {
                    return this.RowCount / this.PageSize;
                }
                else
                {
                    return this.RowCount / this.PageSize  +1;
                }
            }
        }
        /// <summary>
        /// 总记录数，如果不设置该值则直接返回当前页数量
        /// </summary>
        public int RowCount
        {
            get
            {
                return ViewState[this.ClientID + "$RowCount"].Convert<int>(false);
            }
            set
            {
                ViewState[this.ClientID + "$RowCount"] = value;
            }
        }
        /// <summary>
        /// 获取或设置当前显示页的索引。
        /// </summary>
        public override int PageIndex
        {
            get
            {
                return ViewState[this.ClientID + "$PageIndex"].Convert<int>(false);
            }
            set
            {
                ViewState[this.ClientID + "$PageIndex" ]= value;
            }
        }
        

 

        #endregion

        #region 默认样式
        public GridView():base()
        {
            Custom();
        }
        protected void Custom()
        {
            this.CellPadding = 1;
            this.CellSpacing = 2;
            this.AlternatingRowStyle.CssClass = "row2";
            this.RowStyle.CssClass = "row1";
            this.CssClass = "tab";
            this.AutoGenerateColumns = false;
            this.Attributes["border"] = "0";
            this.AllowSorting = true;
            this.AllowPaging = true;
            this.PagerSettings.Visible = false;
            this.PageSize = 10;
           
        }
         

        #endregion

        #region 排序
        /// <summary>
        /// 当前使用的排序表达式，不包含排序方向
        /// </summary>
        public string CurrentSortExpression
        {
            get
            {
                if (ViewState[this.ClientID + "_CurrentSortExpression"] == null)
                {
                    var field = GetDefaultSortField();
                    if (field == null)
                        throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，当前列表控件未设置排序字段");
                    else
                    {
                        ViewState[this.ClientID + "_CurrentSortExpression"] = field.SortExpression;
                        return field.SortExpression;
                    }
                }
                else  
                {
                    return ViewState[this.ClientID + "_CurrentSortExpression"].ToString();
                }
            }
            set
            {
                ViewState[this.ClientID + "_CurrentSortExpression"] = value;
            }
        }
        /// <summary>
        /// 当前使用的排序方向
        /// </summary>
        protected SortDirection CurrentSortDirection
        {
            get {
                if (ViewState[this.ClientID + "_CurrentSortDirection"] == null)
                    return SortDirection.Ascending;
                else
                    return ViewState[this.ClientID + "_CurrentSortDirection"].Convert<SortDirection>();
            }
            set
            {
                ViewState[this.ClientID + "_CurrentSortDirection"] = value;
            }
        }
        /// <summary>
        ///当前使用的排序表达式，包含排序方向
        /// </summary>
        public override string SortExpression
        {
            get
            {
                string result = null;
                var order = "";
                if (this.CurrentSortExpression.IndexOf(",") != -1)
                    order = this.CurrentSortExpression.Split(',')[0];
                else
                    order = this.CurrentSortExpression;
                if (CurrentSortDirection == SortDirection.Ascending)
                    order += " asc";
                else
                    order += " desc";
                if (this.CurrentSortExpression.IndexOf(",") != -1)
                    result = this.CurrentSortExpression.Replace(this.CurrentSortExpression.Split(',')[0],
                        order);
                else
                    result = order;
                return result;



                //if (CurrentSortDirection == SortDirection.Ascending)
                //{
                //    if (this.CurrentSortExpression.IndexOf(",") != -1)
                //    {
                //        var orders=this.CurrentSortExpression.Split(',').Where(p=>p.EmptyString()!=null);
                //        if (orders.Count() >= 1)
                //        {
                //            var d = orders.First();

                //        }
                //    }
                //    else
                //    {
                //        return this.CurrentSortExpression + " asc";
                //    }
                //    return this.CurrentSortExpression + " asc";
                //}
                //else
                //    return this.CurrentSortExpression + " desc";
            }
 
        }
        //public string OrderExpression
        //{
        //    get
        //    {
        //        this.so
        //    }
        //    set
        //    {
        //    }
        //}l
        protected override void OnSorting(GridViewSortEventArgs e)
        {
            OnSortFieldChange(e.SortExpression);
            e.SortDirection = this.CurrentSortDirection;
            base.OnSorting(e);
        }
        /// <summary>
        /// 更改排序列件引发
        /// </summary>
        /// <param name="sortExpression"></param>
        protected void OnSortFieldChange(string sortExpression)
        {
            string _ascIcon = "<img  src='/images/desc3.gif' />";//正序图片
            string _descIcon = "<img  src='/images/desc2.gif' />";//倒序图片
            string _defsortIcon = "<img  src='/images/desc1.gif' />";//默认图片

            foreach (DataControlField dcField in this.Columns)//设置各列的排序方式
            {
                if (dcField is TemplateField)
                {
                    var field = dcField as TemplateField;
                    var icon = _defsortIcon;
                    if (!string.IsNullOrEmpty(field.SortExpression))//只针对设置了排序表达式的列
                    {
                        if (field.SortExpression == sortExpression)
                        {
                            if (field.HeaderText.IndexOf(_ascIcon) == -1 && field.HeaderText.IndexOf(_descIcon) == -1)
                            {
                                if (field.DefaultSortDirection == SortDirection.Ascending)
                                    icon = _ascIcon;
                                else
                                    icon = _descIcon;
                            }
                            else if (field.HeaderText.IndexOf(_ascIcon) != -1)
                            {
                                icon = _descIcon;
                            }
                            else if (field.HeaderText.IndexOf(_descIcon) != -1)
                            {
                                icon = _ascIcon;
                            }
                            this.CurrentSortExpression = sortExpression;
                            this.CurrentSortDirection = (icon == _ascIcon) ? SortDirection.Ascending : SortDirection.Descending;
                        }
                        field.HeaderText = field.HeaderText.Replace(_ascIcon, "")
                                .Replace(_descIcon, "").Replace(_defsortIcon, "") + icon;
                    }
                }
            }
            this.PageIndex = 0;
        }
        /// <summary>
        /// 获取默认排序列
        /// 如果不存在排序列则抛出异常,或未设置默认排序列则抛出异常
        /// </summary>
        /// <returns></returns>
        protected TemplateField GetDefaultSortField()
        {
            if (!this.AllowSorting)
                return null;
            bool isExistDefault = false;
            TemplateField result = null;
            foreach (DataControlField dcf in this.Columns)//设置各列的排序方式
            {
                if (dcf is TemplateField)
                {
                    var tf = dcf as TemplateField;

                    if (tf.DefaultSortField && isExistDefault)
                        throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，当前列表控件不允许存在两个以上的默认排序表达式");
                    else if (tf.DefaultSortField)
                    {
                        isExistDefault = true;
                        if (string.IsNullOrEmpty(tf.SortExpression))
                            throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，当前列表控件设置了默认排序列，但未设置默认排序表达式");
                        result = tf;
                    }
                }
            }
            return result;
        }
        /// <summary>
        /// 重置默认排序
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public bool ResetDefaultSortField(string keyword)
        {
            TemplateField nf = GetTemplateFieldByKeyword(keyword);
            if (nf == null)
                return false;
            TemplateField of = null;
            bool sortExist = false;
            try
            {
                of = GetDefaultSortField();sortExist=true;
            }
            catch { }
            if (sortExist)
            {
                of.DefaultSortField = false;
            }
            nf.DefaultSortField = true;
            OnSortFieldChange(nf.SortExpression);

            return true;
        }
        #endregion

        #region 继承
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.EmptyDataTemplate = new CustomGridViewTemplate(this);


            //设置排序，
            this.Page.PreLoad += delegate(object sender,EventArgs ee)
            {
                if (!Page.IsPostBack)
                {
                    var sortField = GetDefaultSortField();
                    if (sortField != null)
                    {
                        OnSortFieldChange(CurrentSortExpression);
                    }

                }
                    
                SetCheckField();
                SetKeyField();
                SetSerialNoField();
            };
        }
        /// <summary>
        /// 使用指定的 System.Web.UI.HtmlTextWriter 对象将 Web 服务器控件内容呈现给客户端浏览器。
         /// </summary>
         /// <param name="writer"></param>
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            base.Render(writer);
            RenderPager(writer);
             
            
        }
        /// <summary>
        /// 分页代码生成
        /// </summary>
        /// <param name="writer"></param>
        protected void RenderPager(System.Web.UI.HtmlTextWriter writer)
        {
  
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "mpage");
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            writer.Write(string.Format("共 {0} 条记录 ", this.RowCount.ToString()));
            if (this.PageIndex <= 0)
            {
                writer.Write("<a href=\"javascript:\" disabled=\"disabled\">首页</a> ");
                writer.Write("<a href=\"javascript:\" disabled=\"disabled\">上一页</a> ");
            }
            else
            {
                writer.Write(string.Format("<a href=\"{0};\">首页</a> ",
                    Page.ClientScript.GetPostBackClientHyperlink(this, "Page$First")));
                writer.Write(string.Format("<a href=\"{0};\">上一页</a> ",
                    Page.ClientScript.GetPostBackClientHyperlink(this, "Page$Prev")));
            }
            if (this.PageIndex >= this.PageCount-1)
            {
                writer.Write("<a href=\"javascript:\" disabled=\"disabled\">上一页</a> ");
                writer.Write("<a href=\"javascript:\" disabled=\"disabled\">未页</a> ");
            }
            else
            {
                writer.Write(string.Format("<a href=\"{0};\">下一页</a> ",
                    Page.ClientScript.GetPostBackClientHyperlink(this, "Page$Next")));
                writer.Write(string.Format("<a href=\"{0};\">未页</a> ",
                    Page.ClientScript.GetPostBackClientHyperlink(this, "Page$Last")));
            }
          
            writer.Write(string.Format("页次: <span  class=\"hl_\">{0}</span>/{1}页 ",(this.PageIndex+1).ToString(),this.PageCount.ToString()));
            writer.Write("转到第 ");
            writer.AddAttribute(HtmlTextWriterAttribute.Onchange,
                string.Format("javascript:setTimeout('{0}',0)",
                Page.ClientScript.GetPostBackEventReference(this, "Page$Num").Replace("'", @"\'")));
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_PageSelect");
            writer.AddAttribute(HtmlTextWriterAttribute.Name,this.UniqueID+"$PageSelect");
            writer.RenderBeginTag(HtmlTextWriterTag.Select);
            for (int i = 1; i <= this.PageCount; i++)
            {
                if (i == this.PageIndex+1)
                    writer.Write(string.Format("<option selected=\"selected\">{0}</option>", i.ToString()));
                else
                    writer.Write(string.Format("<option>{0}</option>", i.ToString()));
            }
            writer.RenderEndTag();
            writer.Write("页");
            writer.RenderEndTag();
 
        }
        /// <summary>
        /// 事件回发
        /// </summary>
        /// <param name="eventArgument"></param>
        protected override void RaisePostBackEvent(string eventArgument)
        {
            #region 分页
            if (this.AllowPaging)
            {
                string[] strs = eventArgument.Split('$');
                if (strs.Length >= 2)
                {
                    if (strs[0] == "Page")
                    {
                        PagePostBackEvent(eventArgument);
                        return;
                    }
                }
            }
            #endregion
            base.RaisePostBackEvent(eventArgument);
        }
        /// <summary>
        /// 分页回发控制
        /// </summary>
        /// <param name="eventArgument"></param>
        private void PagePostBackEvent(string eventArgument)
        {
            if (this.AllowPaging)
            {
                string[] strs = eventArgument.Split('$');
                int newPageIndex = 0;
                switch (strs[1])
                {
                    case "First":
                        newPageIndex = 0;
                        break;
                    case "Prev":
                        if (this.PageIndex > 0)
                            newPageIndex = this.PageIndex - 1;
                        break;
                    case "Next":
                        if (this.PageIndex < this.PageCount)
                            newPageIndex = this.PageIndex + 1;
                        break;
                    case "Last":
                        newPageIndex = this.PageCount - 1;
                        break;
                    default:
                        var index = 0;
                        if (Page.Request.Form[this.UniqueID + "$PageSelect"].Convert<int>(out index))
                        {
                            newPageIndex = index - 1;
                        }
                       
                        break;
                }
                OnPageIndexChanging(new GridViewPageEventArgs(newPageIndex));
                return;
            }

        }
   
        #endregion

        #region 选择列
        protected void SetCheckField()
        {
            bool exits = false;
            foreach (DataControlField dcf in this.Columns)//设置各列的排序方式
            {
                if (dcf is TemplateField)
                {
                    var tf = dcf as TemplateField;
                    if (tf.IsCheckField)
                    {
                        if (exits)
                            throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，当前控件只允许设置一个选择字段");
                       tf.HeaderText = "<input type=\"checkbox\"  class=\"cbSel\" />";
                        exits = true;
                    }
                }
            }
        }
        protected void SetKeyField()
        {
            bool exits = false;
            foreach (DataControlField dcf in this.Columns)//设置各列的排序方式
            {
                if (dcf is TemplateField)
                {
                    var tf = dcf as TemplateField;
                    if (tf.IsKeyField)
                    {
                        if (exits)
                            throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，当前控件只允许设置一个标识字段");
                        //tf.Visible = true;
                        exits = true;
                    }
                }
            }
        }
        protected void SetSerialNoField()
        {
            bool exits = false;
            foreach (DataControlField dcf in this.Columns)//设置各列的排序方式
            {
                if (dcf is TemplateField)
                {
                    var tf = dcf as TemplateField;
                    if (tf.IsSerialNoField)
                    {
                        if (exits)
                            throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，当前控件只允许设置一个序号字段");
                        tf.HeaderText = "序号";
                        exits = true;
                    }
                }
            }
        }
        /// <summary>
        /// 获取选中项
        /// </summary>
        /// <returns></returns>
        public string[] GetCheckKeys()
        {
            int keyFieldNum=-1;
            int checkFieldNum = -1;
            int index = 0;
            foreach (DataControlField dcf in this.Columns)//设置各列的排序方式
            {
                index++;
                if (dcf is TemplateField)
                {
                    var tf = dcf as TemplateField;
                    if (tf.IsCheckField)
                        checkFieldNum = index;
                    if (tf.IsKeyField)
                        keyFieldNum = index;
                }
            }
            if(keyFieldNum==-1)
                throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，控件缺少标识字段");
            if(checkFieldNum==-1)
                throw SiteInfo.Instance.WarnFactory.CreateWarn("页面错误，控件缺少选择字段");
            var result = new List<string>();
            foreach (GridViewRow gvr in this.Rows)
            {
               var objCheckBox= gvr.Cells[checkFieldNum-1].FindControl("cbIsCheckField");
               if (objCheckBox == null)
                   throw SiteInfo.Instance.WarnFactory.CreateWarn( WarnCode.UnKnow );
               var objLabel = gvr.Cells[keyFieldNum - 1].FindControl("KeyLabel");
               if (objLabel == null)
                   throw SiteInfo.Instance.WarnFactory.CreateWarn("列表控件未找到标识子控件");
               var checkBox = (CheckBox)objCheckBox;
               var label = (System.Web.UI.WebControls.Label)objLabel;
               if (checkBox.Checked)
               {
                   result.Add(label.Text);
               }
            }
            return result.ToArray();
        }
        #endregion

        /// <summary>
        /// 根据关键字获取相应的列
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public TemplateField GetTemplateFieldByKeyword(string keyword)
        {

            foreach (var c in this.Columns)
            {
                if (c is TemplateField)
                {
                    var field = (TemplateField)c;
                    if (field.Keyword == keyword)
                        return field;
                }
            }
            return null;
        }
       
    }
    public class TemplateField : System.Web.UI.WebControls.TemplateField
    {
        private string _keyword = Guid.NewGuid().ToString();
        /// <summary>
        /// 字段关键字
        /// </summary>
        public string Keyword { get { return _keyword; } set { _keyword = value; } }
        /// <summary>
        /// 是否为默认排序字段
        /// </summary>
        public bool DefaultSortField { get; set; }
        /// <summary>
        /// 默认排序方向
        /// </summary>
        public SortDirection DefaultSortDirection { get; set; }
        /// <summary>
        /// 是否为选择字段，为true时该字段自动显示复选框
        /// </summary>
        public bool IsCheckField { get; set; }
        /// <summary>
        /// 是否为标识字段，如果设置IsCheckField一般需设置该值，该属性方便gridview返回选中列的标识
        /// 属性为true时需要设置ItemTemplate，并直接Eval标识值
        /// </summary>
        public bool IsKeyField { get; set; }
        /// <summary>
        /// 排序字段,该字属性为true时自动对字段进行序号排序
        /// </summary>
        public bool IsSerialNoField { get; set; }
        public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
        {
            base.InitializeCell(cell, cellType, rowState, rowIndex);
            if ( DataControlCellType.DataCell == cellType)
            {
                if (this.IsCheckField)
                {
                    var checkBox = new CheckBox();
                    checkBox.ID = "cbIsCheckField";
                    cell.Controls.Add(checkBox);
                }
                if (this.IsSerialNoField)
                {
                    if (this.Control is GridView)
                    {
                        var gv = (GridView)this.Control;
                        int index = gv.PageIndex * gv.PageSize + rowIndex+1;
                        cell.Text = index.ToString();
                    }
                }
            }
        }
        
    }
    public class CustomGridViewTemplate : ITemplate
    {

        GridView _gridView = null;
        private DataControlRowType _templateType;
        private string _columnName;
        private string _dataType;
        public CustomGridViewTemplate(GridView gridView)
        {
            _gridView = gridView;
        }
        /// <summary>
        /// 此方法为 GridView执行DataBind方法后触发执行
        /// 按行顺序向下执行(行->行中各列)
        /// </summary>
        /// <param name="container"></param>
        public void InstantiateIn(System.Web.UI.Control container)
        {
            var html = "";
            foreach (TemplateField column in _gridView.Columns)
            {
                if (column.Visible)
                    html += string.Format("<th>{0}</th>", column.HeaderText);
            }
            html = string.Format("<div><table class='w100_ empty'><tr>{0}</tr><tr  class='row1'><td colspan='99'>暂无数据</td></tr></table></div>", html);
            Literal literal = new Literal();
            literal.Text = html;
            container.Controls.Add(literal);

        }
    }
 



}
